﻿using System.Collections.Generic;
using System.Management;
using System;
using ClusterAwareProperties;
using ClusterAwareAdmin.Properties;
using ClusterAwareWMI;

namespace ClusterAwareAdmin
{
    /// <summary>
    /// Wrapper property to class Disk actions
    /// </summary>
    public class DiskMethods
    {
        #region private properties

        private readonly ClusterManagerAdmin _managerclass;

        #endregion

        #region Constructor

        private DiskMethods()
        {
        }

        /// <summary>
        /// Create Class DiskMethods
        /// </summary>
        /// <param name="managerclass">Instance of ClusterManager class</param>
        public DiskMethods(ClusterManagerAdmin managerclass)
            : this()
        {
            _managerclass = managerclass;
        }

        #endregion

        #region public Methods

        /// <summary>
        /// if Exists Disk
        /// </summary>
        /// <param name="diskName">Disk name</param>
        /// <returns>True if exists</returns>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameter diskName name is empty
        /// </exception>
        /// <remarks>
        /// Not Cachebled result
        /// </remarks>
        public bool ExistDisk(string diskName)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(diskName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "diskName"));
            }
            try
            {
                var dsk = new ClusterWmiHelpper().GetDisk(diskName, _managerclass.ScopeManager);
                return (dsk != null);
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// get list of disk 
        /// </summary>
        /// <returns>Array of class Disk</returns>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected
        /// </exception>
        /// <remarks>
        /// Not Cachebled result
        /// </remarks>
        public DiskProperty[] GetDisks()
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            try
            {
                return new ClusterWmiHelpper().GetDisks(_managerclass.ScopeManager);
            }
            catch
            {
                //Windows 2003 not have DiskClass WMI Manager
                return new List<DiskProperty>().ToArray();
            }
        }

        /// <summary>
        /// Get a Disk
        /// </summary>
        /// <param name="diskName">name Disk</param>
        /// <returns>Disk class</returns>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameter disk name is empty, 
        /// Disk not exists
        /// </exception>
        /// <remarks>
        /// Not Cachebled result
        /// </remarks>
        public DiskProperty GetDisk(string diskName)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(diskName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "diskName"));
            }
            try
            {
                return new ClusterWmiHelpper().GetDisk(diskName, _managerclass.ScopeManager);
            }
            catch
            {
                //Windows 2003 not have DiskClass WMI Manager
                return null;
            }
        }

        /// <summary>
        /// if Exists AvailableDisk
        /// </summary>
        /// <param name="diskName">Available diskname</param>
        /// <returns>True if exists</returns>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameter Availabledisk name is empty
        /// </exception>
        /// <remarks>
        /// Not Cachebled result
        /// </remarks>
        public bool ExistAvailableDisk(string diskName)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(diskName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "diskName"));
            }
            try
            {
                var dsk = new ClusterWmiHelpper().GetAvailableDisk(diskName, _managerclass.ScopeManager);
                return (dsk != null);
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// get list of Availabledisk 
        /// </summary>
        /// <returns>Array of class AvailableDisk</returns>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected
        /// </exception>
        /// <remarks>
        /// Not Cachebled result
        /// </remarks>
        public DiskProperty[] GetAvailableDisks()
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            try
            {
                return new ClusterWmiHelpper().GetAvailableDisks(_managerclass.ScopeManager);
            }
            catch
            {
                //Windows 2003 not have DiskClass WMI Manager
                return new List<DiskProperty>().ToArray();
            }
        }

        /// <summary>
        /// Get a AvailableDisk
        /// </summary>
        /// <param name="diskName">name AvailableDisk</param>
        /// <returns>Disk class</returns>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameter disk name is empty, 
        /// AvailableDisk not exists
        /// </exception>
        /// <remarks>
        /// Not Cachebled result
        /// </remarks>
        public DiskProperty GetAvailableDisk(string diskName)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(diskName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "diskName"));
            }
            try
            {
                return new ClusterWmiHelpper().GetAvailableDisk(diskName, _managerclass.ScopeManager);
            }
            catch
            {
                //Windows 2003 not have DiskClass WMI Manager
                return null;
            }
        }

        /// <summary>
        /// Adds the available disk to the cluster.
        /// </summary>
        /// <param name="diskAvailable">
        /// Disk class Availabled
        ///</param>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// AvailableDisk not exists
        /// </exception>
        /// <remarks>
        /// Not Cachebled result
        /// </remarks>
        /// <returns>
        /// The path to the created physical disk resource.
        /// </returns>
        public string AddAvailableDiskToCluster(DiskProperty diskAvailable)
        {
            string ret;
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (diskAvailable == null)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "DiskAvailable"));
            }
            try
            {
                // ReSharper disable AssignNullToNotNullAttribute
                var outParams = diskAvailable.Instance.InvokeMethod("AddToCluster", null, null);
                // ReSharper restore AssignNullToNotNullAttribute
                // ReSharper disable PossibleNullReferenceException
                ret = outParams["Path"].ToString();
                // ReSharper restore PossibleNullReferenceException
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Disks.AddAvailableDiskToCluster", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "Disks.AddAvailableDiskToCluster", ex.Message), ex);
            }
            return ret;
        }

        #endregion

    }
}
